-
Notifications
You must be signed in to change notification settings - Fork 136
[WellSQL Migration] Migrate WCNewVisitorStatsModel to Room
#14592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Warning: "'Enum.values()' is recommended to be replaced by 'Enum.entries' since 1.9"
Warning: "Unreachable code"
Warning: "Call chain on a collection type may be simplified"
FYI: This is done in preparation to the subsequent WellSQL to Room table migration.
FYI: This is done in preparation to the subsequent WellSQL to Room table migration.
FYI: This is done in preparation to the subsequent WellSQL to Room table migration.
FYI: This change includes but is not limited to the: - Entity Introduction - DAO Introduction (With Test) - WCAndroidDatabase Migration - Code Adjustments (Store) - Test Adjustments (Store)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR migrates WCNewVisitorStatsModel from WellSQL to Room database as part of the ongoing database migration effort. The change replaces WellSQL-based persistence with modern Room annotations and DAOs while maintaining the same functionality.
Key changes:
- Migrates
WCNewVisitorStatsModelfrom WellSQL annotations to Room entity - Replaces
WCVisitorStatsSqlUtilswithNewVisitorStatsDaousing Room queries - Updates database schema and migration scripts
Reviewed Changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| WCNewVisitorStatsModel.kt | Converted from WellSQL @Table to Room @Entity with composite primary key |
| NewVisitorStatsDao.kt | New Room DAO replacing WellSQL utility functions |
| WCStatsStore.kt | Updated to use new DAO instead of SQL utils, made functions suspend |
| WCVisitorStatsSqlUtils.kt | Deleted - functionality moved to Room DAO |
| WCAndroidDatabase.kt | Added new entity and DAO registration, version bump |
| WellSqlConfig.kt | Added migration to drop old WellSQL table |
| Test files | Updated to use new Room-based approach and test patterns |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
...uxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/NewVisitorStatsDao.kt
Show resolved
Hide resolved
| } | ||
| } ?: return mapOf() | ||
| } | ||
| return mapOf() |
Copilot
AI
Sep 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return statement at line 213 is unreachable because the function always returns from within the rawStats?.let block or the ?: return mapOf() expression on line 212. Remove the unreachable return statement.
| return mapOf() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, and that's exactly what I did, actually a bit confused by this comment of yours... 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the comment is incorrect - I guess LLM wrongly interpreted the inner return (line 203).
A suggestion I have is to refactor for a single return point, but that's not critical.
val visitorMap = rawStats?.let { visitorStatsModel ->
val periodIndex = visitorStatsModel.getIndexForField(WCNewVisitorStatsModel.VisitorStatsField.PERIOD)
val fieldIndex = visitorStatsModel.getIndexForField(WCNewVisitorStatsModel.VisitorStatsField.VISITORS)
if (periodIndex != -1 && fieldIndex != -1) {
getVisitorsMap(
periodIndex = periodIndex,
fieldIndex = fieldIndex,
dataList = visitorStatsModel.dataList
)
} else {
emptyMap()
}
}
return visitorMap ?: emptyMap()
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCStatsStore.kt
Show resolved
Hide resolved
Generated by 🚫 Danger |
📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
|
|
📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## trunk #14592 +/- ##
============================================
+ Coverage 38.35% 38.38% +0.02%
Complexity 9715 9715
============================================
Files 2058 2058
Lines 115287 115226 -61
Branches 15341 15337 -4
============================================
+ Hits 44220 44224 +4
+ Misses 66970 66906 -64
+ Partials 4097 4096 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…to migrate/wc-new-visitor-stats-model-to-room
|
I unassigned myself. Since I’ll be AFK until September 19, can you take a look at this, @JorgeMucientes or @hichamboushaba? |
Oh, thanks @irfano and apologies, I (or algorithm) wasn't aware you're on AFK. 🫣 FYI: I am not sure if you had the change to use this
Since I've assign @JorgeMucientes on this previous #14520 PR of mine already, I'll go ahead and assign you @hichamboushaba on this one, let me know how you feel and I'll find an alternative. 🙏 |
wzieba
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I don't know the answers on the domain of the Stats, so I'll leave this to the product team. I also couldn't perform detailed tests due to log in issues (internal details: p1757495577372719-slack-CGPNUU63E ) but I don't want to keep this PR on hold because of this.
| } | ||
| } ?: return mapOf() | ||
| } | ||
| return mapOf() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the comment is incorrect - I guess LLM wrongly interpreted the inner return (line 203).
A suggestion I have is to refactor for a single return point, but that's not critical.
val visitorMap = rawStats?.let { visitorStatsModel ->
val periodIndex = visitorStatsModel.getIndexForField(WCNewVisitorStatsModel.VisitorStatsField.PERIOD)
val fieldIndex = visitorStatsModel.getIndexForField(WCNewVisitorStatsModel.VisitorStatsField.VISITORS)
if (periodIndex != -1 && fieldIndex != -1) {
getVisitorsMap(
periodIndex = periodIndex,
fieldIndex = fieldIndex,
dataList = visitorStatsModel.dataList
)
} else {
emptyMap()
}
}
return visitorMap ?: emptyMap()
| <ID>UnitTestNamingRule:WCShippingLabelStoreTest.kt$WCShippingLabelStoreTest$@Test fun `verify shipping address`()</ID> | ||
| <ID>UnitTestNamingRule:WCStatsSqlUtilsTest.kt$WCStatsSqlUtilsTest$@Test @Suppress("LongMethod") fun testGetRawRevenueStatsForSiteAndUnit()</ID> | ||
| <ID>UnitTestNamingRule:WCStatsSqlUtilsTest.kt$WCStatsSqlUtilsTest$@Test @Suppress("LongMethod") fun testSimpleInsertionAndRetrievalOfRevenueStats()</ID> | ||
| <ID>UnitTestNamingRule:WCStatsStoreTest.kt$WCStatsStoreTest$@Suppress("LongMethod") @Test fun testGetQuantityForMonths()</ID> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work on this (here and previous PRs) - a good reminder to look at the baseline (Detekt or Lint) when working on technical debt 🏅
Sounds good @ParaskP7, but I hope it's fine not to review this until tomorrow 🙂 |
Totally fine @hichamboushaba , many thanks + appreciated, and no rush, no rush at all! 🙇 ❤️ |
hichamboushaba
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @ParaskP7 👏, this works as expected, and I'll try to answer your questions below:
OrderStatsRestClient.fetchNewVisitorStats(...): This is where the only place where WCNewVisitorStatsModel get instantiated and its isCustomField is being driven by startDate != null, questions:
- Why is startDate driving this isCustomField field? 🤔
- Due to the above, during my testing, isCustomField was always 1, or else true, just because startDate was always non-null, no matter what option the user chooses from the UI (My store -> Performance -> Calendar icon). Is that expected? 🤔
I also didn't know, but after looking at the history of this field, I understand now, back in 2019 when this table was added, the app supported a "custom" date option in stats graph (that option was removed later), and the way the team worked on this was that they treated the granularity option as a date (so StatsGranularity.DAYS was equivalent to "Today") unless the startDate was specified, startDate was specified only for the custom date option in the graph.
This was confusing, and we got rid of this when we brought back the "Custom" date option last year, and we changed the logic so that startDate was always required.
I overlooked the column isCustomField of the DB when I worked on this, otherwise I should have deleted it as it's always true now.
Now whether you should delete it or not, I'll leave it up to you to decide this 🙂.
WCNewVisitorStatsModel: During my testing, when using Custom from the UI (My store -> Performance -> Calendar icon), I noticed that the Visitors (and Conversion) data is unavailable for any date range picked other than a specific "single" day. Is that expected? 🤔
Yes, it's expected, but this has nothing to do with this migration, the Visitors count that's shown on the graph when no entry is selected is driven by the VisitorSummaryStatsEntity, and this used Room since it was added.
Please let me know if you have any other questions, but the main point here is that this is ready for merge unless you want to delete the isCustomField column.
|
👋 @hichamboushaba and thanks for reviewing/testing this, as well as answering my questions, much appreciated! 🙇 ❤️
Thank you for digging as deep to answer my question! 🙏
Yea, I think it might be better (an opportunity) for us to delete this unused WILL DO 🏃 💨💨💨 |
…to migrate/wc-new-visitor-stats-model-to-room # Conflicts: # libs/fluxc-plugin/schemas/org.wordpress.android.fluxc.persistence.WCAndroidDatabase/64.json
Due to 146ebde a merge conflict appeared which got solved via 781b01b, with the main '64.json' file, but also a hidden merge conflict on 'WCAndroidDatabase', which includes: - const val WC_DATABASE_VERSION = 65 - AutoMigration(from = 64, to = 65), I accepted the current version of '64.json' and created a new one, the '65.json' because the database version for this exact change has now been updated to '65' (from '64').
PR Comment: https://github.com/woocommerce/woocommerce-android/pull/ 14592#pullrequestreview-3212230060
FYI: This is now done @hichamboushaba (cc @wzieba): e1694cd (mainly) Please take another look and let me know if everything looks and works as expected, thank you much! 🙏 PS: No rush! 🆗 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCStatsStore.kt
Show resolved
Hide resolved
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCStatsStore.kt
Show resolved
Hide resolved
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCStatsStore.kt
Show resolved
Hide resolved
hichamboushaba
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @ParaskP7, thanks so much for the code cleanup
Awesome @hichamboushaba , thanks so much for yet another code review/testing session on that! 🙇 ❤️ 🚀 FYI: I'll merge this first thing on Monday. |
Closes: AINFRA-554
Description
This PR migrates
WCNewVisitorStatsModelfrom WellSQL to Room database.Reviewers
In addition to having @wzieba as the main "code" reviewer on this change, I added⚠️ ):
@woocommerce/android-developersto randomly assign a product engineers as an "extra" review (@irfano@hichamboushaba), primarily because, both ontrunkand this PR branch, I've these questions (OrderStatsRestClient.fetchNewVisitorStats(...): This is where the only place whereWCNewVisitorStatsModelget instantiated and itsisCustomFieldis being driven bystartDate != null, questions:startDatedriving thisisCustomFieldfield? 🤔isCustomFieldwas always1, or elsetrue, just becausestartDatewas always non-null, no matter what option the user chooses from the UI (My store->Performance->Calendaricon). Is that expected? 🤔WCNewVisitorStatsModel: During my testing, when usingCustomfrom the UI (My store->Performance->Calendaricon), I noticed that theVisitors(andConversion) data is unavailable for any date range picked other than a specific "single" day. Is that expected? 🤔Testing information
My store+PerformanceMy storetab and verify that thePerformancesection is being correctly populated with the expected number ofVisitors.Performancesection, click on theCalendaricon and selectToday. Verify that the section's title changes to something likeToday Sep 9, 2025and that the number ofVisitorsis updated accordingly.This Week,This MonthandThis Yearand verify everything is working as expected.App Inspection, check theNewVisitorStatsEntitytable, and notice (isCustomFieldis1.Customand edit the section's title picking a specific "single" day likeSep 9 - Sep 9, clickSAVE. Verify that the section's title changes to something likeCustom Sep 9, 2025 - Sep 9, 2025and that the number ofVisitorsis updated accordingly.Sep 8 - Sep 9, clickSAVE. Verify that the section's title changes to something likeCustom Sep 8, 2025 - Sep 9, 2025and notice (Visitors(andConversion) is actually unavailable. (see alsoReviewersrelated questions).App Inspection, check theNewVisitorStatsEntitytable, and verify thatisCustomFieldis1.Images/gif
RELEASE-NOTES.txtif necessary. Use the "[Internal]" label for non-user-facing changes.